package com.wondream.myframework.app.common.aspect;

import com.wondream.myframework.app.common.annotation.DecryptAnno;
import com.wondream.myframework.app.common.annotation.DecryptDbField;
import com.wondream.myframework.app.common.exception.BusinessExeceptionCode;
import com.wondream.myframework.app.common.util.FieldUtils;
import com.wondream.myframework.app.common.util.SensitiveFieldUtils;
import com.wondream.myframework.app.common.util.SpringUtils;
import com.wondream.myframework.app.vo.base.OpRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * esa解密处理
 */
@Aspect
@Component
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE + 10)
public class DecryptDbFieldAspect {

    /**
     * 切入点
     */
    @Pointcut("execution(public * com.wondream.myframework.app.client.esa..*.*(..))")
    public void pointCut(){

    }

    /**
     * 拦截要执行的目标方法
     */
    @Around("pointCut()")
    public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
        String op = "DecryptDbFieldAspect.aroundAdvice";
        long startTimestamp = System.currentTimeMillis();
        MethodSignature ms = (MethodSignature) pjp.getSignature();
        Method method = ms.getMethod();
        Object[] arguments = pjp.getArgs();
        log.info("op:"+method.getName());
        if(ArrayUtils.isEmpty(arguments)){
            return pjp.proceed();
        }
        Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(ms.getName(), method.getParameterTypes());
        Annotation[][] parameterAnnotations = realMethod.getParameterAnnotations();
        int arrIndex = 1;
        for (Annotation[] annotations : parameterAnnotations) {
            arrIndex++;
            for (Annotation annotation : annotations) {
                if (annotation instanceof DecryptDbField && arguments[arrIndex] != null) {
                    arguments[arrIndex] = SensitiveFieldUtils.decryptDbField(arguments[arrIndex].toString());
                }
            }
        }
        for (Object argument : arguments) {
            SensitiveFieldUtils.decryptDbField(argument);
        }
        return pjp.proceed();
    }
}
